package cn.easyutil.util.javaUtil;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;

public class CommandUtil {
	private String ip;
	private String username;
	private String password;
	private String charset;
	
	public String getIp() {
		if(StringUtil.isEmpty(ip)){
			throw new NullPointerException("remote connection ip must be not null,please set field of [ip]");
		}
		return ip;
	}
	
	public void setIp(String ip) {
		this.ip = ip;
	}
	
	public String getUsername() {
		if(StringUtil.isEmpty(username)){
			throw new NullPointerException("remote connection username must be not null,please set field of [username]");
		}
		return username;
	}
	
	public void setUsername(String username) {
		this.username = username;
	}
	
	public String getPassword() {
		if(StringUtil.isEmpty(password)){
			throw new NullPointerException("remote connection password must be not null,please set field of [password]");
		}
		return password;
	}
	
	public void setPassword(String password) {
		this.password = password;
	}
	
	public String getCharset() {
		if(charset == null){
			charset = "UTF-8";
		}
		return charset;
	}
	
	public void setCharset(String charset) {
		this.charset = charset;
	}
	public CommandUtil(){}
	public CommandUtil(String ip,String username,String password){
		this.ip = ip;
		this.username = username;
		this.password = password;
	}
	/**
	 * 执行操作系统命令
	 * @param command 执行命令
	 * @return
	 */
	public static List<String> execute(String command){
		String charset = "GBK";
		String osName = System.getProperty("os.name");
		if(osName.trim().toUpperCase().contains("WINDOWS")){
			if(!command.startsWith("cmd /c")){
				command = "cmd /c "+command;
			}
		}
		if(osName.trim().toUpperCase().contains("LINUX")){
			charset = "UTF-8";
		}
		return execute(command,charset);
	}

	/**
	 * 执行操作系统命令
	 * @param command 执行命令
	 * @param charset	执行后返回信息的编码
	 * @return
	 */
	public static List<String> execute(String command,String charset){
		InputStream in = null;
		try {
			Process process = Runtime.getRuntime().exec(command);
			process.waitFor();
			in = process.getInputStream();
			List<String> buff = new ArrayList<String>();
			byte[] but = new byte[10240000];
			int length = 0;
			while ((length = in.read(but))!=-1) {
				if(charset == null){
					charset = "utf-8";
				}
				String str = new String(but,0,length,charset);
				buff.add(str);
			}
			LoggerUtil.debug(CommandUtil.class, "excuting command ["+command+"] succcess");
			return buff;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}finally{
			try {
				in.close();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
	}
	
	/**
	 * 执行操作系统命令
	 * @param ip 目标服务器ip
	 * @param username 目标服务器登陆用户名
	 * @param password 目标服务器登陆密码
	 * @param command 要执行的命令
	 * @param charset 返回结果的编码集
	 * @return
	 */
	public static List<String> execute(String ip,String username,String password,String...command){
		return execute(new CommandUtil(ip,username,password), command);
	}
	/**
	 * 执行操作系统命令
	 * @param ip 目标服务器ip
	 * @param username 目标服务器登陆用户名
	 * @param password 目标服务器登陆密码
	 * @param command 要执行的命令
	 * @param charset 返回结果的编码集
	 * @return
	 */
	public static List<String> execute(CommandUtil easyCommandUtil,String...command){
		Connection conn = null;
		try{  
            //构造一个连接器，传入一个需要登陆的ip地址，连接服务  
            conn = new Connection(easyCommandUtil.getIp());  
            conn.connect();  
            //用户验证，传入用户名和密码  
            boolean isAuthenticated = conn.authenticateWithPassword(easyCommandUtil.getUsername(), easyCommandUtil.getPassword());  
            if (isAuthenticated == false){
            	LoggerUtil.debug(CommandUtil.class, "the server ["+easyCommandUtil.getIp()+"] connect exception");
            	throw new IOException("the server ["+easyCommandUtil.getIp()+"] connect exception");
            }
            List<String> result = new ArrayList<String>();
            for (int i = 0; i < command.length; i++) {
            	List<String> re = exString(conn, command[i], easyCommandUtil.getCharset());
            	result.add(JsonUtil.beanToJson(re));
			}
            return result;
        }catch (Exception e){  
        	LoggerUtil.debug(CommandUtil.class, "excuting command ["+command+"] failed");
        	LoggerUtil.error(CommandUtil.class, e);
            throw new RuntimeException(e);
        }finally{
        	conn.close();
        }
	}
	
	/**
	 * 执行命令
	 * @param conn 远程连接
	 * @param command 要执行的命令
	 * @param charset	返回结果的编码集
	 * @return
	 */
	private static List<String> exString(Connection conn,String command,String charset){
		List<String> list = new ArrayList<String>();
		Session sess = null;
		BufferedReader br = null;
		InputStream stdout = null;
		try{  
			//打开一个会话session，执行linux命令  
	        sess = conn.openSession();  
	        sess.execCommand(command);  
	        //接收目标服务器上的控制台返回结果,输出结果。  
	        stdout = new StreamGobbler(sess.getStdout());
	        br = new BufferedReader(new InputStreamReader(stdout));  
	        while (true){  
	            String line = br.readLine();
	            if (line == null){
	            	break;  
	            }
	            list.add(new String(line.getBytes(),charset));
	        }  
	        LoggerUtil.debug(CommandUtil.class, "excuting command ["+command+"] success");
	        return list;
        }catch (Exception e){
        	LoggerUtil.debug(CommandUtil.class, "excuting command ["+command+"] failed");
        	LoggerUtil.error(CommandUtil.class, e);
            throw new RuntimeException(e);
        }finally{
        	//关闭session和connection 
	        try {
				br.close();
				stdout.close();
				sess.close();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
        }
	}

	public static void main(String[] args) {
		List<String> execute = execute("cmd /c dir D://");
		System.out.println(JsonUtil.beanToJson(execute));
	}
}
